﻿//Copyright 2008 Kristian Gundry And Rune Juhl-Petersen
//This file is part of Plain.

//Plain is free software: you can redistribute it and/or modify
//it under the terms of the GNU Lesser General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//any later version.

//Plain is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU Lesser General Public License for more details.

//You should have received a copy of the GNU Lesser General Public License
//along with Plain.  If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Web.Mvc;
using Plain.Web.Mvc.Binders;
using Plain.Search;
using Plain.DuckTyping;

namespace Plain.Web.Mvc.Controllers {
    public class PlainController<T> : Controller {
		
		Type[] typeArgs = { typeof(T), typeof(T).GetProperty("Id").PropertyType };
		
		public PropertyFactory<T> p {
			get;
			set;
		}
		
        public PlainController() {
			p = new PropertyFactory<T>();
            if (!this.Binders.ContainsKey(typeof(T))) {
                Type binderType = typeof(PlainBinder<,>);        
                Type binder = binderType.MakeGenericType(typeArgs);
                IModelBinder binderInstance = Activator.CreateInstance(binder) as IModelBinder;

                this.Binders[typeof(T)] = binderInstance;
				
            }
        }
		
		public T Get(object id){
			if(id.GetType() != typeof(T).GetProperty("Id").PropertyType)
				throw new Exception();
			object dao = Plain.PlainApplication.Config.DaoFactory.GetMethod<object> ("GetDao", typeArgs).Call ();
			return (T)dao.CallMethod("Get", id);
		}
		       
		public IList<T> GetAll(){
			object dao = Plain.PlainApplication.Config.DaoFactory.GetMethod<object>("GetDao",typeArgs).Call();
			return (IList<T>)dao.CallMethod("GetAll");
		}
		
		public IList<T> Search(Criteria crit){
			 object dao = Plain.PlainApplication.Config.DaoFactory.GetMethod<object>("GetDao",typeArgs).Call();
			 return (IList<T>)dao.CallMethod("Search", crit);
		}
		
		public TT Get<TT>(object id){
			Type[] args = { typeof(TT), typeof(TT).GetProperty("Id").PropertyType };
			if(id.GetType() != typeof(TT).GetProperty("Id").PropertyType)
				throw new Exception();
			object dao = Plain.PlainApplication.Config.DaoFactory.GetMethod<object>("GetDao",args).Call();
			return (TT)dao.CallMethod("Get", id);
		}
		
		public IList<TT> GetAll<TT>(){
			Type[] args = { typeof(TT), typeof(TT).GetProperty("Id").PropertyType };
			object dao = Plain.PlainApplication.Config.DaoFactory.GetMethod<object>("GetDao",args).Call();
			return (IList<TT>)dao.CallMethod("GetAll");
		}
		
		public IList<TT> Search<TT>(Criteria crit){
			Type[] args = { typeof(TT), typeof(TT).GetProperty("Id").PropertyType };
			object dao = Plain.PlainApplication.Config.DaoFactory.GetMethod<object>("GetDao",args).Call();
			return (IList<TT>)dao.CallMethod("Search", crit);
		}
		
		public ViewResult View(Criteria crit){
			return View(Search(crit));
		}
	}
}